﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TicketsPhone.Domain.Access;
using TicketsPhone.Domain.Entities;
using TicketsPhone.Domain.Utils;
using TicketsPhone.Web.Utils;
using TicketsPhone.Web.Models;
using System.Text;
using TicketsPhone.Domain.Models;
using TicketsPhone.Entidades;

namespace TicketsPhone.Web.Controllers
{
    public class TurnosController : Controller
    {
        TurnoRepositorio _turno = new TurnoRepositorio();
        EntidadRepositorio _entidad = new EntidadRepositorio();
        SucursalRepositorio _sucursal = new SucursalRepositorio();
        TramiteRepositorio _tramite = new TramiteRepositorio();
        UsuarioRepositorio _usuario = new UsuarioRepositorio();


        public ActionResult Index()
        {
            ProcesarTurno();
            //cel=3176353838                celular del usuario
            //tramite=1                     id del tramite que se desea hacer
            //fTurno=18/09/2011          fecha deseada para el turno
            //sucursal=1                    id de la sucursal
            //key=fdsfsd65fsd5fds78fff      celular+palabraclave+tramite
            //hIni=10:30                    hora inicio
            //hFin=10:40                    hora final


            //cel=3176353838&tramite=1&fTurno=18/09/2011&key=fdsfsd65fsd5fds78fff&sucursal=1&hIni=10:30&hFin=10:40
            return View();
        }

        public ActionResult Solicitud()
        {
            SolicitudModel model = ProcesarTurno();
            return View(model);
        }

        public ActionResult Cancelar()
        {
            return View(CancelarTurno());
        }

        public ActionResult Simulador()
        {

            SucursalRepositorio _sucursal = new SucursalRepositorio();
            _sucursal.Objeto = new Sucursal();
            TramiteRepositorio _tramite = new TramiteRepositorio();
            _tramite.Objeto = new Tramite();


            TurnoFormModel model = new TurnoFormModel();
            model.Sucursales = _sucursal.Filtrar();
            model.Tramites = _tramite.Filtrar();
            
            model.Tramite = new TramiteRelacional();
            model.Sucursal = new SucursalRelacional();
            model.HoraFin = DateTime.Now.ToShortTimeString();
            model.HoraInicio = DateTime.Now.ToShortTimeString(); 
            model.FechaTurno = DateTime.Now.ToShortDateString();


            return View(model);
        }

       


        [HttpPost]
        public ActionResult Simulador(TurnoFormModel model)
        {
            Usuario usuario = _usuario.Cargar(model.Usuario);
            
            Turno turno = new Turno();
            turno.Usuario.IdUsuario = usuario.IdUsuario.Value;
            turno.Tramite.IdTramite = model.Tramite.IdTramite;
            turno.IdSucursal = model.Sucursal.IdSucursal;
            turno.IdEstadoTurno = EstadoTurno.Solicitado;
            turno.HoraInicio = new Hora(model.HoraInicio);
            turno.HoraFin = new Hora(model.HoraFin);
            turno.FechaTurno = Convert.ToDateTime(model.FechaTurno, new System.Globalization.CultureInfo("es-CO"));
            turno.FechaSolicitud = DateTime.Now;
            turno.Codigo = GenerarCodigo();
            _turno.Objeto = turno;
            _turno.Crear();


            SucursalRepositorio _sucursal = new SucursalRepositorio();
            _sucursal.Objeto = new Sucursal();
            TramiteRepositorio _tramite = new TramiteRepositorio();
            _tramite.Objeto = new Tramite();


            model.Sucursales = _sucursal.Filtrar();
            model.Tramites = _tramite.Filtrar();

            return View(model);
        }

        /// <summary>
        /// Retorna el xml que se va cargar en los telefonos
        /// </summary>
        /// <returns></returns>
        public ActionResult XML()
        {
            //XmlGeneradoModel model = new XmlGeneradoModel();
            //model.Xml = GenerarXml();

            Response.ContentType = "text/xml";
            Response.Write(GenerarXml());
            return View();
        }

        public ActionResult Listar()
        {
            TurnoFormModel model = new TurnoFormModel();
            model.Listado = _turno.ObtenerTurnosActivosPorSucursal(SesionModel.IdSucursal, true);
            model.CajaActual = _usuario.ObtenerCajaActual(SesionModel.IdUsuario);
            return View(model);
        }

        public ActionResult Editar(int id)
        {
            TurnoFormModel model = new TurnoFormModel();
            model.Objeto = _turno.Cargar(id);
            return View(model);
        }

        public ActionResult ActualizarCajaActual(int id)
        {
            JsonResult json = new JsonResult();
            json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
            json.Data = _usuario.EditarCajaActual(SesionModel.IdUsuario, id);
            return json;
        }


        [HttpPost]
        public ActionResult Editar(TurnoFormModel model, int id)
        {
            if (ModelState.IsValid)
            {
                _turno.AtenderTurno(id, model.Objeto.IdEstadoTurno.Value, model.Objeto.Comentarios);
                _sucursal.EditarTurnoEnCaja(SesionModel.CajaActual, 0, SesionModel.IdSucursal);
                model.Javascript = Scripts.RedireccionConMensaje("/Turnos/Listar", "Turno actualizado correctamente");
            }

            return View(model);
        }

        public ActionResult Taquillero()
        {
            TaquilleroModel model = new TaquilleroModel();
            model.cajerosActivos = this.CargarCajerosActivos();
            return View(model);
        }

        #region Ajax
        /// <summary>
        /// Actualiza el estado del turno
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult TomarTurno(int id)
        {
            return new JsonResult() { Data = new TurnoFormModel().TomarTurno(id), JsonRequestBehavior = JsonRequestBehavior.AllowGet };            
        }

        #endregion

        #region Metodos
        /// <summary>
        /// Realiza las validaciones necesarias y guarda el turno
        /// </summary>
        private SolicitudModel ProcesarTurno()
        {
            SolicitudModel model = new SolicitudModel();


            try
            {
                if (Web.Utils.Utilidades.ExisteRequest("cel") && Web.Utils.Utilidades.ValidarRequest("tramite") && Web.Utils.Utilidades.ValidarRequest("sucursal"))
                {
                    string celular = HttpContext.Request.QueryString["cel"];
                    Usuario usuario = _usuario.Cargar(celular);

                    if (!usuario.IdUsuario.HasValue)
                    {
                        _usuario.Objeto = new Usuario();
                        _usuario.Objeto.Nombre = celular;
                        _usuario.Objeto.Apellidos = celular;
                        _usuario.Objeto.Email = celular;
                        _usuario.Objeto.Apellidos = celular;
                        _usuario.Objeto.IdSucursal = Convert.ToInt32(HttpContext.Request.QueryString["sucursal"]);
                        _usuario.Objeto.Perfil.IdPerfil = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["perfilCliente"]);
                        _usuario.Objeto.FechaRegistro = DateTime.Now;
                        _usuario.Objeto.EsAdministrador = false;
                        _usuario.Objeto.Activo = true;
                        _usuario.Objeto.Pass = Utilidades.Utilidades.MD5(celular);
                        _usuario.Objeto.Entidad.IdEntidad = _sucursal.Cargar(_usuario.Objeto.IdSucursal.Value).Entidad.IdEntidad.Value;
                        _usuario.Objeto.IdUsuario = _usuario.Crear();

                        usuario = _usuario.Objeto;
                    }

                    if (GuardarTurno(usuario))
                        model.Respuesta = "<respuesta actualizacion=\"false\" procesado=\"true\" error=\"La solicitud ha sido procesada\"></respuesta>";
                    else
                        model.Respuesta = "<respuesta actualizacion=\"false\" procesado=\"false\" error=\"La solicitud no ha sido procesada. Ocurrio un error.\"></respuesta>";
                }
                else
                {
                    model.Respuesta = "<respuesta actualizacion=\"false\" procesado=\"false\" error=\"La solicitud no ha sido procesada por falta de parametros\"></respuesta>";
                    LogErroresRepositorio.GuardarLog("URL CON FALTA DE PARAMETROS EN SOLICITUD--->"+Request.Url.AbsolutePath);
                }
            }
            catch (Exception e)
            {
                LogErroresRepositorio.GuardarLog(e);
                model.Respuesta = "<respuesta actualizacion=\"false\" procesado=\"false\" error=\"La solicitud no ha sido procesada. Ocurrio un error.\"></respuesta>";
            }


            Response.ContentType = "text/xml";
            Response.Write(model.Respuesta);
            return model;

        }

        private SolicitudModel CancelarTurno()
        {
            SolicitudModel model = new SolicitudModel();
            
            try
            {
                if (Web.Utils.Utilidades.ExisteRequest("id") && !string.IsNullOrEmpty(HttpContext.Request.QueryString["clave"]))
                {
                    //valida que la clave sea valida
                    Turno turno = _turno.Cargar(Convert.ToInt32(HttpContext.Request.QueryString["id"]));
                    if (turno.Codigo.ToLower().Equals(HttpContext.Request.QueryString["clave"].ToLower()))
                    {
                        _turno.EditarEstadoTurno(Convert.ToInt32(HttpContext.Request.QueryString["id"]), EstadoTurno.NoAsistencia);
                        model.Respuesta = "<respuesta actualizacion=\"false\" procesado=\"true\" error=\"El turno ha sido cancelado\"></respuesta>";
                    }
                    else
                    {
                        model.Respuesta = "<respuesta actualizacion=\"false\" procesado=\"false\" error=\"La clave del turno es invalida\"></respuesta>";
                    }
                    
                }
                else
                {
                    model.Respuesta = "<respuesta actualizacion=\"false\" procesado=\"false\" error=\"La cancelación no ha sido procesada. Faltan parametros.\"></respuesta>";
                }
            }
            catch (Exception e)
            {
                LogErroresRepositorio.GuardarLog(e);
                model.Respuesta = "<respuesta actualizacion=\"false\" procesado=\"false\" error=\"La cancelación no ha sido procesada. Ocurrio un error.\"></respuesta>";
            }

            
            
            Response.ContentType = "text/xml";
            Response.Write(model.Respuesta);
            return model;
        }


        /// <summary>
        /// Devuelve un codigo para asignar al turno. El codigo asignado no se encuetra repetido
        /// </summary>
        /// <returns>Codigo generado</returns>
        private string GenerarCodigo()
        {
            string codigo = Utilidades.Utilidades.GenerarClave(7, 7);

            if (_turno.EsCodigoValido(codigo, EstadoTurno.Cerrado))
            {
                return codigo;
            }
            else
            {
                return GenerarCodigo();
            }
        }

        public string GenerarXml()
        {

            StringBuilder strXml = new StringBuilder();
            List<Entidad> entidades = _entidad.ObtenerActivos();
            strXml.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            //abre nodo prioncipal
            strXml.AppendFormat("<ticketsPhone>");

            foreach (Entidad entidad in entidades)
            {
                //abre entidad
                strXml.AppendFormat("<entidad id=\"{0}\" nombre=\"{1}\">", entidad.IdEntidad, entidad.Nombre);

                _sucursal.Objeto.Entidad.IdEntidad = entidad.IdEntidad;
                List<Sucursal> sucursales = _sucursal.Filtrar();

                foreach (Sucursal sucursal in sucursales)
                {
                    //abre sucursal
                    strXml.AppendFormat("<sucursal id=\"{0}\" nombre=\"{1}\" direccion=\"{2}\" telefono=\"{3}\" >", sucursal.IdSucursal, sucursal.Nombre, sucursal.Direccion, sucursal.Telefono);


                    List<TramitesSucursal> tramites = _sucursal.ObtenerTramitesAsignados(sucursal.IdSucursal.Value);

                    strXml.AppendFormat("<tramites>");

                    foreach (TramitesSucursal tramiteSucursal in tramites)
                    {
                        Tramite tramite = _tramite.Cargar(tramiteSucursal.Tramite.IdTramite);

                        strXml.AppendFormat("<tramite id=\"{0}\" nombre=\"{1}\" duracion=\"{2}\"  >", tramite.IdTramite, tramite.Nombre, tramite.Duracion);

                        strXml.AppendFormat("<requisitos>{0}</requisitos>", tramite.Requisitos);

                        //cierra tramite
                        strXml.Append("</tramite>");
                    }

                    strXml.AppendFormat("</tramites>");

                    strXml.AppendFormat("<horarios>");


                    List<Horario> horarios = _sucursal.ObtenerHorario(sucursal.IdSucursal.Value);

                    foreach (Horario horario in horarios)
                    {
                        strXml.AppendFormat("<horario dia=\"{0}\" horaInicio=\"{1}\" horaFin=\"{2}\" />", horario.Dia, horario.HoraInicio, horario.HoraFin);
                    }

                    strXml.AppendFormat("</horarios>");

                    //cierra sucursal
                    strXml.Append("</sucursal>");
                }

                //cierra entidad
                strXml.Append("</entidad>");
            }

            strXml.AppendFormat("</ticketsPhone>");

            return strXml.ToString();
        }


        private bool  GuardarTurno(Usuario usuario)
        {
            Turno turno = new Turno();
            turno.Usuario.IdUsuario = usuario.IdUsuario.Value;
            turno.Tramite.IdTramite = int.Parse(HttpContext.Request.QueryString["tramite"]);
            turno.IdSucursal = int.Parse(HttpContext.Request.QueryString["sucursal"]);
            turno.IdEstadoTurno = EstadoTurno.Solicitado;
            turno.HoraInicio = new Hora(HttpContext.Request.QueryString["hIni"]+":01");
            turno.HoraFin = new Hora(HttpContext.Request.QueryString["hFin"]);
            turno.FechaTurno = DateTime.Now;//Convert.ToDateTime(HttpContext.Request.QueryString["fTurno"], new System.Globalization.CultureInfo("es-CO"));
            turno.FechaSolicitud = DateTime.Now;
            turno.Codigo = GenerarCodigo();
            _turno.Objeto = turno;
            return _turno.Crear() > 0;


            
        }

        private List<CajeroActivo> CargarCajerosActivos()
        { 
            //Primero consultar el numero de cajeros activos en los ultimos 10 min
            Horario horario = new Horario();
            DateTime horaInicio = DateTime.Now.AddMinutes(-5);
            DateTime horaFin = DateTime.Now.AddMinutes(5);
            horario.HoraInicio = new Hora() { Horas = horaInicio.Hour, Minutos = horaInicio.Minute };
            horario.HoraFin = new Hora() { Horas = horaFin.Hour, Minutos = horaFin.Minute };
            horario.Dia = DateTime.Now.DayOfWeek;
            horario.Sucursal.IdSucursal = SesionModel.IdSucursal;
            //carga los cajeros activos
            int cajeros = _sucursal.ObtenerCajerosActivos(horario);
            _sucursal.InsertarCajerosPorTurno(SesionModel.IdSucursal, cajeros);
            //devuelve el listado de cajas en el momento con los códigos seleccionados
            return _sucursal.ObtenerInfoCajeros(SesionModel.IdSucursal);
        }


        
        #endregion



    }
}
